package ThreadPool.jike.demo14;

import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @param
 * @author oyz
 * @version 1.0.4
 * @description: 转账案例
 * @date 2022/5/17 8:48
 */
public class Account {


    private int balance;
    private final Lock lock = new ReentrantLock();


    ExecutorService es = new ThreadPoolExecutor(
            50, 500,
            60L, TimeUnit.SECONDS,
            //注意要创建有界队列
            new LinkedBlockingQueue<Runnable>(2000),
            //建议根据业务需求实现ThreadFactory
            r->{
                return new Thread(r, "echo-"+ r.hashCode());
            },
            //建议根据业务需求实现RejectedExecutionHandler
            new ThreadPoolExecutor.CallerRunsPolicy());


    // 转账
    void transfer(Account tar, int amt) throws InterruptedException {
        while (true) {
            if (this.lock.tryLock()) {
                try {
                    if (tar.lock.tryLock()) {
                        try {
                            this.balance -= amt;
                            tar.balance += amt;
                            //新增：退出循环
                            break;
                        } finally {
                            tar.lock.unlock();
                        }
                    }//if
                } finally {
                    this.lock.unlock();
                }
            }//if
            //新增：sleep一个随机时间避免活锁
            Thread.sleep(new Random().nextInt(1000 + 1));

        }//while
    }//transfer

    public static void main(String[] args) {

        new Thread(()->{
            try {
                new Account().transfer(new A(),1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();







    }

    static class A extends Account{

    }

    static class B extends Account{

    }
}




